home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cpp_libs / nihcl-30.lha / nihcl-3.0 / lib / Exception.c < prev    next >
C/C++ Source or Header  |  1990-05-19  |  5KB  |  215 lines

  1. /* Exception.c -- NIHCL exception handling
  2.  
  3.     THIS SOFTWARE FITS THE DESCRIPTION IN THE U.S. COPYRIGHT ACT OF A
  4.     "UNITED STATES GOVERNMENT WORK".  IT WAS WRITTEN AS A PART OF THE
  5.     AUTHOR'S OFFICIAL DUTIES AS A GOVERNMENT EMPLOYEE.  THIS MEANS IT
  6.     CANNOT BE COPYRIGHTED.  THIS SOFTWARE IS FREELY AVAILABLE TO THE
  7.     PUBLIC FOR USE WITHOUT A COPYRIGHT NOTICE, AND THERE ARE NO
  8.     RESTRICTIONS ON ITS USE, NOW OR SUBSEQUENTLY.
  9.  
  10. Author:
  11.     K. E. Gorlen
  12.     Bg. 12A, Rm. 2033
  13.     Computer Systems Laboratory
  14.     Division of Computer Research and Technology
  15.     National Institutes of Health
  16.     Bethesda, Maryland 20892
  17.     Phone: (301) 496-1111
  18.     uucp: uunet!nih-csl!kgorlen
  19.     Internet: kgorlen@alw.nih.gov
  20.     February, 1986
  21.  
  22. Function:
  23.  
  24. NIHCL exception handling.
  25.     
  26. $Log:    Exception.c,v $
  27.  * Revision 3.0  90/05/20  00:19:30  kgorlen
  28.  * Release for 1st edition.
  29.  * 
  30. */
  31.  
  32. #include "ExceptAct.h"
  33. #include <osfcn.h>
  34. #include <libc.h>
  35. #include <errlib.h>
  36. #include <stdarg.h>
  37.  
  38. #include "nihclconfig.h"
  39. #include "nihclerrs.h"
  40. #include "nihclerrsx.h"
  41.  
  42. static char rcsid[] = "$Header: /afs/alw.nih.gov/unix/sun4_40c/usr/local/src/nihcl-3.0/share/lib/RCS/Exception.c,v 3.0 90/05/20 00:19:30 kgorlen Rel $";
  43.  
  44. static ExceptionEnv topExceptionEnv;
  45.  
  46. static Catch topCatch;
  47. Catch* Catch::stackTop = &topCatch;
  48. ExceptionEnv* ExceptionEnv::stackTop = 0;
  49. ExceptionEnv* ExceptionEnv::lastResort = 0;
  50.  
  51. void ExceptionEnv::raise(int exception)
  52. {
  53.     if (exception == 0) {
  54.         cerr << "Tried to RAISE exception code 0\n";
  55.         abort();
  56.     }
  57.     if (prev == 0) {    // i.e.,  this == lastResort
  58.         cerr << "NIHCL: fatal: Unhandled exception code " << exception << '\n';
  59.         exit(1);
  60.     }
  61.     pop();
  62. #if STACK_GROWS_DOWN
  63.     for (register Catch* p = Catch::stackTop->next; p < (Catch*)this && p != Catch::stackTop; p = p->next)
  64. #else
  65.     for (register Catch* p = Catch::stackTop->next; p > (Catch*)this && p != Catch::stackTop; p = p->next)
  66. #endif
  67.         p->obj->destroyer();
  68.     Catch::stackTop->next = p;
  69.     p->prev = Catch::stackTop;
  70.     longjmp(env,exception);
  71. }
  72.  
  73. Catch::Catch()
  74. {
  75.     next = prev = this;
  76.     obj = Object::nil;
  77. }
  78.  
  79. Catch::Catch(Object* ob)
  80. {
  81.     obj = ob;
  82.     void* top[2];
  83. #if STACK_GROWS_DOWN
  84.     if ((void*)this < (void*)ExceptionEnv::stackTop && (void*)this > (void*)top) {    // this on stack
  85. #else
  86.     if ((void*)this > (void*)ExceptionEnv::stackTop && (void*)this < (void*)top) {    // this on stack
  87. #endif
  88.         next = stackTop->next;
  89.         prev = stackTop;
  90.         stackTop->next = this;
  91.         next->prev = this;
  92.     }
  93.     else next = 0;        // Catch object was allocated by new
  94. }
  95.  
  96. Catch::~Catch()
  97. {
  98.     if (next != 0) {
  99.         next->prev = prev;
  100.         prev->next = next;
  101.     }
  102.     obj->destroyer();
  103. }
  104.  
  105. static ExceptionActionTbl mainExceptionActionTbl;
  106. ExceptionActionTbl* ExceptionActionTbl::active = &mainExceptionActionTbl;
  107.  
  108. #ifdef sparc
  109. // Use magic name to make stdarg work
  110. #define sev_ __builtin_va_alist
  111. #endif
  112.  
  113. void NIHCL::setError(int err, int sev_, ...)
  114. {
  115.     ExceptionActionTbl::active->act((unsigned)err,sev_);
  116. #ifdef TRACE
  117. printf("seterror> Error No: %d  Severity: %d\n",err,sev_);
  118. #endif
  119.     errno = err;
  120.         char buf[132],buf0[132];
  121.  
  122.     errfac_errorText(err,buf/*OUT*/);
  123.      
  124.     char* p = errfac_argumentCodes(err);
  125. #ifdef TRACE
  126. printf("seterror> argument codes %s\n",p);
  127. #endif
  128.     va_list ap;
  129.     va_start(ap,sev_);
  130.     while ( *p != '\0' ) { // set up next arg
  131.       errfac_prepNextArg(buf/*IN*/,buf0/*OUT*/);
  132.       switch ( *(p++) ) {
  133.          case 'I': 
  134.         int i = va_arg(ap,int);
  135.              sprintf(buf,buf0,i);
  136.                   break;
  137.          case 'S':
  138.         char* s = va_arg(ap,char*);
  139.              sprintf(buf,buf0,s);
  140.             break;
  141.          case 'D':
  142.             double d = va_arg(ap,double);
  143.              sprintf(buf,buf0,d);
  144.             break;
  145.          default : // ignored
  146.             break;
  147.          }// end switch
  148.           }// end while
  149.     va_end(ap);
  150.  
  151.     int severity = (sev_ < 0)? sev_:(errfac_severity(err));
  152.     errfac_errorMessage(severity,buf);
  153.     if ( errfac_isExitSeverity(severity) ) {
  154.        cerr << "NIHCL: fatal: Tried to continue after error "
  155.         << err <<'\n';
  156.        abort();
  157.        }
  158. }
  159.  
  160. ExceptionActionTbl::ExceptionActionTbl()
  161. {
  162.     client_exception_trap = NULL;
  163.     for (register int i=NIHCL__LAST_ERROR-NIHCL__FIRSTERROR; i>=0; i--)
  164.         action[i] = ExceptionAction::ABORT;
  165. }
  166.  
  167. void ExceptionActionTbl::act(unsigned error, int sev)
  168. {
  169.     if (client_exception_trap != NULL) {
  170.         (*client_exception_trap)(error,sev);
  171.     }
  172.     if (error >= NIHCL__FIRSTERROR && error <= NIHCL__LAST_ERROR) {
  173.         switch (action[error-NIHCL__FIRSTERROR]) {
  174.             case ExceptionAction::RAISE: RAISE(error);
  175.             case ExceptionAction::ABORT: return;
  176.         }
  177.     }
  178. }
  179.  
  180. ExceptionAction::ExceptionAction(unsigned error)
  181. {
  182.     if ( (error < NIHCL__FIRSTERROR)||(error > NIHCL__LAST_ERROR) ) {
  183.         setError(NIHCL_BADERRNUM,DEFAULT,"ExceptionAction",error);
  184.         return;
  185.     }
  186.     error_code = error;
  187.     old_action = ExceptionActionTbl::active->action[error-NIHCL__FIRSTERROR];
  188. }
  189.  
  190. ExceptionAction::~ExceptionAction()
  191. {
  192.     ExceptionActionTbl::active->action[error_code-NIHCL__FIRSTERROR] = old_action;
  193. }
  194.  
  195. AbortException::AbortException(unsigned error) : ExceptionAction(error)
  196. {
  197.     ExceptionActionTbl::active->action[error-NIHCL__FIRSTERROR] = ExceptionAction::ABORT;
  198. }
  199.  
  200. RaiseException::RaiseException(unsigned error) : ExceptionAction(error)
  201. {
  202.     ExceptionActionTbl::active->action[error-NIHCL__FIRSTERROR] = ExceptionAction::RAISE;
  203. }
  204.  
  205. ExceptionTrap::ExceptionTrap(exceptionTrapTy xtrap)
  206. {
  207.     old_trap = ExceptionActionTbl::active->client_exception_trap;
  208.     ExceptionActionTbl::active->client_exception_trap = xtrap;
  209. }
  210.  
  211. ExceptionTrap::~ExceptionTrap()
  212. {
  213.     ExceptionActionTbl::active->client_exception_trap = old_trap;
  214. }
  215.